package br.ufmg.ubicomp.utils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

public class XmlParseUtil {

	private static Document parseXml(String result) {
		try {
			// Use JAXP to find a parser
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			// Turn on namespace support
			factory.setNamespaceAware(true);
			DocumentBuilder parser = factory.newDocumentBuilder();

			// Read the entire document into memory
			ByteArrayInputStream bais = new ByteArrayInputStream(result
					.getBytes());
			Document document = parser.parse(bais);
			return document;
		} catch (DOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;

	}

	public static Collection<XmlElement> getXmlElementsFromServer(String result) {
		Document document = parseXml(result); 
		int numberOfObjects = document.getElementsByTagName("object")
				.getLength();
		// Process it starting at the root
		Collection<XmlElement> elements = new ArrayList<XmlElement>();
		if (numberOfObjects > 0) {
			for (int i = 0; i < numberOfObjects; i++) {
				Node obj = document.getElementsByTagName("object").item(i);
				if (obj.getNodeType() == Node.ELEMENT_NODE) {
					XmlElement element = new XmlElement();
					Element object = (Element) obj;
					element.setName(object.getNodeName());
					NamedNodeMap map = object.getAttributes();
					if (map != null) {
						for (int k = 0; k < map.getLength(); k++) {
							Node child = map.item(k);
							String name = child.getNodeName();
							String value = child.getNodeValue();
							System.out.println("Attribute: " + name + ", "
									+ value + "\r\n");
							element.addAttribute(name, value);
						}
					}
					elements.add(element);
				}
			}
		}
		return elements;
	}

	public static Collection<EntityProperties> getEntities(NodeList entities)
	{
		Collection<EntityProperties> list = new ArrayList<EntityProperties>();
		for (int i = 0; i < entities.getLength(); i++) {
			Node entityEntry = entities.item(i);

			if (entityEntry instanceof Element) {
				Element entityElement = (Element) entityEntry;
				EntityProperties ep = new EntityProperties();
				String kind = entityElement.getAttribute("kind");
				ep.setName(kind);
				ep.setType(entityEntry.getNodeName());
				ep.addProperty("kind", kind);
				ep.addProperty("key", entityElement.getAttribute("key"));
			
				NodeList properties = entityElement.getChildNodes();
			
				for (int j = 0; j < properties.getLength(); j++) {
					Node propertyEntry = properties.item(j);
			
					if (propertyEntry instanceof Element) {
						Element propertyElement = (Element) propertyEntry;
			
						Text textNode = (Text) propertyElement
								.getFirstChild();
						String text = textNode!= null && textNode.getData() != null?textNode.getData().trim():"";
			
						if (propertyElement.getTagName().equals("property")) {
							String attributeName = propertyElement
									.getAttribute("name");
							ep.addProperty(attributeName, text);
						}
					}
				}
				list.add(ep);
			}
		}
		return list;
		
	}
	
	public static EntityProperties getEntityProperties(NodeList properties)
	{
		EntityProperties entityProperties = new EntityProperties();
		for (int j = 0; j < properties.getLength(); j++) {
			Node propertyEntry = properties.item(j);
	
			if (propertyEntry instanceof Element) {
				Element propertyElement = (Element) propertyEntry;
	
				Text textNode = (Text) propertyElement
						.getFirstChild();
				String text = textNode.getData().trim();
	
				if (propertyElement.getTagName().equals("property")) {
					String attributeName = propertyElement
							.getAttribute("name");
					entityProperties.getProperties().put(attributeName, text);
				}
			}
		}
		return entityProperties;
		
	}
	
	
}
